using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
namespace HHHFramework
{
    public class AssetBundleManager : MonoSingleton<AssetBundleManager>
    {
        private AssetBundle mainAB = null;
        private AssetBundleManifest manifest = null;
        private Dictionary<string, AssetBundle> abDic = new Dictionary<string, AssetBundle>();
        private string assetBundleUrl
        {
            get {
                if (GameManager.Instance.environmentMode == EnvironmentMode.Developing)
                {
                    return Application.dataPath + "/ArtRes/ab/PC/";
                }
                else if (GameManager.Instance.environmentMode == EnvironmentMode.Test)
                {
                    return Application.dataPath + "/ArtRes/ab/PC/";
                }
                else {
                    return Application.streamingAssetsPath + "/";
                }
               
            }
        }
        private string mainABName
        {
            get { return "PC"; }
        }
        private void LoadMainAndDependences(string abName)
        {
            Debug.Log(assetBundleUrl+ abName);
            //主包加载
            if (mainAB == null)
            {
                mainAB = AssetBundle.LoadFromFile(assetBundleUrl + mainABName);
                manifest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
            }
            //依赖加载
            AssetBundle ab;
            string[] abDependencies = manifest.GetAllDependencies(abName);
            for (int i = 0; i < abDependencies.Length; i++)
            {
                if (!abDic.ContainsKey(abDependencies[i]))
                {
                    ab = AssetBundle.LoadFromFile(assetBundleUrl + abDependencies[i]);
                    abDic.Add(abDependencies[i], ab);
                }
            }
            //加载资源的来源包
            if (!abDic.ContainsKey(abName))
            {
                ab = AssetBundle.LoadFromFile(assetBundleUrl + abName);
                abDic.Add(abName, ab);
            }
        }
        public Object LoadSyncAssetBundle(string abName, string assetName)
        {
            LoadMainAndDependences(abName);
            //加载资源 
            return abDic[abName].LoadAsset(assetName);

        }
        public Object LoadSyncAssetBundle(string abName, string assetName, System.Type type)
        {
            LoadMainAndDependences(abName);
            //加载资源 
            return abDic[abName].LoadAsset(assetName, type);
        }
        public T LoadSyncAssetBundle<T>(string abName, string assetName) where T : Object
        {
            LoadMainAndDependences(abName);
            //加载资源 
            return abDic[abName].LoadAsset<T>(assetName);
        }


        #region ab包异步加载
        public void LoadAsyncAssetBundle(string abName, string assetName, UnityAction<Object> callBack)
        {
            StartCoroutine(ReallyLoadABAsync(abName, assetName, callBack));
        }
        private IEnumerator ReallyLoadABAsync(string abName, string assetName, UnityAction<Object> callBack)
        {
            LoadMainAndDependences(abName);
            AssetBundleRequest abr = abDic[abName].LoadAssetAsync(assetName);
            yield return abr;
            if (abr.asset == null) { Debug.LogError($"{assetName} 加载失败 ! "); }
            else
            {
                callBack?.Invoke(abr.asset);
            }

        }


        public void LoadAsyncAssetBundle(string abName, string assetName, System.Type type, UnityAction<Object> callBack)
        {

            StartCoroutine(ReallyLoadABAsync(abName, assetName, type, callBack));
        }
        private IEnumerator ReallyLoadABAsync(string abName, string assetName, System.Type type, UnityAction<Object> callBack)
        {
            LoadMainAndDependences(abName);
            AssetBundleRequest abr = abDic[abName].LoadAssetAsync(assetName, type);
            yield return abr;
            if (abr.asset == null) { Debug.LogError($"{assetName} 加载失败 ! "); }
            else
            {
                callBack?.Invoke(abr.asset);
            }

        }

        public void LoadAsyncAssetBundle<T>(string abName, string assetName, UnityAction<T> callBack) where T : Object
        {

            StartCoroutine(ReallyLoadABAsync(abName, assetName, callBack));
        }
        private IEnumerator ReallyLoadABAsync<T>(string abName, string assetName, UnityAction<T> callBack) where T : Object
        {
            LoadMainAndDependences(abName);
            AssetBundleRequest abr = abDic[abName].LoadAssetAsync<T>(assetName);
            yield return abr;
            if (abr.asset == null) { Debug.LogError($"{assetName} 加载失败 ! "); }
            else
            {
                callBack?.Invoke(abr.asset as T);
            }

        }



        #endregion
        public void UnLoad(string abName)
        {
            if (abDic.ContainsKey(abName))
            {
                abDic[abName].Unload(false);
                abDic.Remove(abName);
            }

        }
        public void ClerarAB()
        {
            AssetBundle.UnloadAllAssetBundles(false);
            mainAB = null;
            manifest = null;
        }


    }
}